#pragma once

#include "Pseudostate.h"

#include "State.h"
#include "StateMachine.h"

namespace uml {

Pseudostate::Pseudostate(const QString& umlType)
    : NamedElement(umlType) {}

void Pseudostate::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    NamedElement::fromJson(json, errorList);
    Vertex::fromJson(json, errorList);
    kind_ = (PseudostateKind)json.value("kind").toInt((int)kind_);
    state_ = JsonSerializable::create<State>(json.value("state"), errorList);

    stateMachine_ = JsonSerializable::create<StateMachine>(json.value("stateMachine"), errorList);

}

void Pseudostate::toJson(QJsonObject& json) {
    NamedElement::toJson(json);
    Vertex::toJson(json);
    json.insert("kind", (int)kind_);
    if (state_) {
        QJsonObject state_json;
        state_->toJson(state_json);
        json.insert("state", state_json);
    }
    if (stateMachine_) {
        QJsonObject stateMachine_json;
        stateMachine_->toJson(stateMachine_json);
        json.insert("stateMachine", stateMachine_json);
    }
}

/// <summary>
/// kind getter
/// Determines the precise type of the Pseudostate and can be one of: entryPoint,
/// exitPoint, initial, deepHistory, shallowHistory, join, fork, junction, terminate
/// or choice.
/// </summary>
PseudostateKind Pseudostate::kind() const {
    return kind_;
}

/// <summary>
/// kind setter
/// Determines the precise type of the Pseudostate and can be one of: entryPoint,
/// exitPoint, initial, deepHistory, shallowHistory, join, fork, junction, terminate
/// or choice.
/// </summary>
void Pseudostate::setKind(PseudostateKind value) {
    kind_ = value;
}

/// <summary>
/// state getter
/// The State that owns this Pseudostate and in which it appears.
/// </summary>
shared_ptr<State> Pseudostate::state() const {
    return state_;
}

/// <summary>
/// state setter
/// The State that owns this Pseudostate and in which it appears.
/// </summary>
void Pseudostate::setState(shared_ptr<State> value) {
    state_ = value;
}

/// <summary>
/// stateMachine getter
/// The StateMachine in which this Pseudostate is defined. This only applies to
/// Pseudostates of the kind entryPoint or exitPoint.
/// </summary>
shared_ptr<StateMachine> Pseudostate::stateMachine() const {
    return stateMachine_;
}

/// <summary>
/// stateMachine setter
/// The StateMachine in which this Pseudostate is defined. This only applies to
/// Pseudostates of the kind entryPoint or exitPoint.
/// </summary>
void Pseudostate::setStateMachine(shared_ptr<StateMachine> value) {
    stateMachine_ = value;
}

} // namespace uml
